package com.linkallcloud.core.query;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson2.annotation.JSONField;
import com.linkallcloud.core.lang.Strings;
import com.linkallcloud.core.query.Query.GroupOperator;
import com.linkallcloud.core.query.rule.desc.StringRuleDescriptor;

public class WebQuery implements Serializable {
    private static final long serialVersionUID = -7056272723587483018L;

    private List<StringRuleDescriptor> cnds;

    private boolean distinct;
    private boolean mapUnderscoreToCamelCase;

    // 排序条件（非datatables）
    private Orderby orderby;

    public WebQuery() {
        super();
    }

    public static void copyWebQueryFields2Query(WebQuery src, Query dest) {
        if (src == null || dest == null) {
            return;
        }
        dest.setDistinct(src.isDistinct());
        dest.setMapUnderscoreToCamelCase(src.isMapUnderscoreToCamelCase());
        dest.setOrderby(src.getOrderby());
        dest.setGroupOp(GroupOperator.AND);
        dest.setGroups(null);
        if (src.getCnds() != null && !src.getCnds().isEmpty()) {
            for (StringRuleDescriptor rd : src.getCnds()) {
                dest.addRule(rd);
            }
        }
    }

    public Query toQuery() {
        Query result = new Query();
        WebQuery.copyWebQueryFields2Query(this, result);
        return result;
    }

    public List<StringRuleDescriptor> getCnds() {
        return cnds;
    }

    public void setCnds(List<StringRuleDescriptor> cnds) {
        this.cnds = cnds;
    }

    public void addRule(StringRuleDescriptor rule) {
        if (rule != null) {
            if (this.cnds == null) {
                this.cnds = new ArrayList<StringRuleDescriptor>();
                this.cnds.add(rule);
            } else {
                boolean exist = false;
                for (StringRuleDescriptor r : this.cnds) {
                    if (r.getField().equals(rule.getField())) {
                        r.setOp(rule.getOp());
                        r.setType(rule.getType());
                        r.setValue(rule.getValue());
                        exist = true;
                        break;
                    }
                }
                if (!exist) {
                    this.cnds.add(rule);
                }
            }
        }
    }

    public boolean isDistinct() {
        return distinct;
    }

    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }

    public boolean isMapUnderscoreToCamelCase() {
        return mapUnderscoreToCamelCase;
    }

    public void setMapUnderscoreToCamelCase(boolean mapUnderscoreToCamelCase) {
        this.mapUnderscoreToCamelCase = mapUnderscoreToCamelCase;
    }

    public Orderby getOrderby() {
        return orderby;
    }

    public void setOrderby(Orderby orderby) {
        this.orderby = orderby;
    }

    @JSONField(serialize = false)
    public String[] getOrdersSqlFrags() {
        if (orderby != null && orderby.isOrderBySetted()) {
            return orderby.getOrderSqls(isMapUnderscoreToCamelCase());
        }
        return null;
    }

    /**
     * order sql, 比如：id desc,name asc
     * 
     * @return
     */
    @JSONField(serialize = false)
    public String getOrdersSql() {
        String[] orderbys = getOrdersSqlFrags();
        if (orderbys != null && orderbys.length > 0) {
            return Strings.join2(",", orderbys);
        }
        return null;
    }

    /**
     * 是否存在名称是fieldName的rule
     *
     * @param fieldName
     * @return boolean
     */
    public boolean hasRule4Field(String fieldName) {
        if (getCnds() != null && !getCnds().isEmpty()) {
            for (StringRuleDescriptor rd : getCnds()) {
                if (rd.getField().equals(fieldName)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 得到名称是fieldName的rule
     *
     * @param fieldName
     * @return boolean
     */
    public StringRuleDescriptor getRule4Field(String fieldName) {
        if (getCnds() != null && !getCnds().isEmpty()) {
            for (StringRuleDescriptor rd : getCnds()) {
                if (rd.getField().equals(fieldName)) {
                    return rd;
                }
            }
        }
        return null;
    }

    /**
     * 重新设置名称是fieldName的rule的值
     *
     * @param fieldName
     * @param value
     */
    public void resetRule4Field(String fieldName, String value) {
        if (getCnds() != null && !getCnds().isEmpty()) {
            for (StringRuleDescriptor rd : getCnds()) {
                if (rd.getField().equals(fieldName)) {
                    rd.setData(value);
                }
            }
        }
    }

}
